
`define ALUCtrlAND 4'd0
`define ALUCtrlOR 4'd1 
`define ALUCtrlSLT 4'd2
`define ALUCtrlnone 4'd3

`define ALUCtrlADD 4'd4
`define ALUCtrlSUB 4'd5

`define ALUCtrlXOR 4'd6 
`define ALUCtrlNOR 4'd7 
`define ALUCtrlSLLV  4'd8

module ALU(
        input [31:0] A, // ALU first operand
        input [31:0] B, // ALU second operand
        input [3:0] M, // ALU operation select
        output [31:0] C, // ALU result
        output Z // ALU zero flag
    );

    assign C=(M==`ALUCtrlnone)?32'd0:
           (M==`ALUCtrlAND)?A&B:
           (M==`ALUCtrlOR)?A|B:
           (M==`ALUCtrlADD)?A+B:
           (M==`ALUCtrlSUB)?A-B:
           (M==`ALUCtrlSLT)?A<B:
           (M==`ALUCtrlXOR)?A^B:
           (M==`ALUCtrlNOR)?~(A|B):
           (M==`ALUCtrlSLLV)?B<<A[4:0]:32'd0;

    assign Z=((A-B)==32'd0)?1'b1:1'b0;

endmodule
